<?php

/**
 * Формирует URL с указанными параметрами.
 *
 * Параметры:
 * - uri     — путь, относительно которого нужно сформировать URL. если не
 *             указано, будет взят текущий адрес;
 * - path    — надо посмотреть, используется ли это где-нибудь;
 * - query   — массив GET-параметров, которые нужно добавить в URL;
 * - through — массив наименований сквозных GET-параметров;
 *
 * @access  public
 * @param   array   $params
 * @param   Smarty  $smarty
 */
function smarty_function_url($params, &$smarty) {
    require_once $smarty->_get_plugin_filepath('shared','explode_param');
    list($path, $query) = smarty_function_url_get_base($params);
    $through_default = smarty_explode_param($smarty, 'through_default');
    $t_params = array();
    if (isset($params['through'])) {
        $t_value = $params['through'];
        if (is_string($t_value)) {
            $t_params = explode(',', $t_value);
        } elseif (true === $t_value) {
            $t_params = null;
        } else {
            $smarty->trigger_error("url: incorrect 'through' value", E_USER_WARNING);
        }
    }

    if (is_array($t_params)) {
        $query = array_extract($query, array_merge($through_default, $t_params));
    }

    if (isset($params['path'])) {
        $path = $params['path'];
    }
    if (isset($params['query'])) {
        $query = array_merge($query, $params['query']);
    }
    smarty_function_url_clear($params);
    echo $path . smarty_function_url_compose(array_merge($query, $params));
}

/**
 * Возвращает основные параметры URL'a (путь и параметры запроса), от которых
 * будем плясать.
 *
 * @param   array   $params
 * @return  arary
 */
function smarty_function_url_get_base($params) {
    $uri = isset($params['uri']) ? $params['uri'] : $_SERVER['REQUEST_URI'];
    list($path, $query) = smarty_function_url_explode($uri, '?');
    return array($path, smarty_function_url_parse($query));
}

/**
 * Разбивает строку на две части по указанному разделителю.
 *
 * @param   string  $string
 * @param   string  $delimiter
 * @return  array
 */
function smarty_function_url_explode($string, $delimiter) {
    return array_pad(explode($delimiter, $string, 2), 2, null);
}

/**
 * Разбирает строку запроса в массив параметров
 *
 * @param   string  $query
 * @return  array
 */
function smarty_function_url_parse($query) {
    $params = array();
    foreach (array_filter(explode('&', $query)) as $pair) {
        list($name, $value) = smarty_function_url_explode($pair, '=');
        $params[$name] = $value;
    }
    return array_filter($params);
}

/**
 * Собирает строку запроса из ассоциативного массива параметров.
 *
 * @param   array   $array
 * @return  string
 */
function smarty_function_url_compose($params) {
    $pairs = array();
    foreach (array_filter($params) as $name => $value) {
        $pairs[] = $name . '=' . $value;
    }
    return count($pairs) > 0 ? '?' . implode('&amp;', $pairs) : '';
}

/**
 * Удаляет из параметров "системные" параметры.
 *
 * @param   string  $string
 * @return  array
 */
function smarty_function_url_clear(&$params) {
    $params = array_diff_key($params, array_flip(array('uri', 'path', 'query', 'through')));
}
